package fi.foyt.cs.api;

import org.restlet.Application;
import org.restlet.Restlet;
import org.restlet.resource.ServerResource;
import org.restlet.routing.Router;
import org.restlet.security.Authorizer;

import fi.foyt.cs.Settings;
import fi.foyt.cs.api.items.ListStashedItemsResource;
import fi.foyt.cs.api.items.StashItemsResource;
import fi.foyt.cs.api.scenes.FindNearbyScenesResource;
import fi.foyt.cs.api.system.PingResource;
import fi.foyt.cs.api.tasks.FindTasksResource;
import fi.foyt.cs.api.tasks.PerformGeneralTaskResource;
import fi.foyt.cs.api.users.AcceptFriendRequestResource;
import fi.foyt.cs.api.users.AddFriendResource;
import fi.foyt.cs.api.users.FindNearbyUsersResource;
import fi.foyt.cs.api.users.GetInventoryResource;
import fi.foyt.cs.api.users.ListConfirmedFriendsResource;
import fi.foyt.cs.api.users.ListUnconfirmedFriendsResource;
import fi.foyt.cs.api.users.MeResource;
import fi.foyt.cs.api.users.RejectFriendRequestResource;
import fi.foyt.cs.api.users.RemoveFriendResource;

public class APIApplication extends Application {
  
  @Override
  public synchronized Restlet createInboundRoot() {

    Router router = new Router(getContext());

    // Users
    
    attachProtected(router, "/users/me", MeResource.class, false);
    attachProtected(router, "/users/findNearbyUsers?lat={lat}&lng={lng}", FindNearbyUsersResource.class, true);
    attachProtected(router, "/users/getInventory", GetInventoryResource.class, false);
    attachProtected(router, "/users/listConfirmedFriends", ListConfirmedFriendsResource.class, false);
    attachProtected(router, "/users/listUnconfirmedFriends", ListUnconfirmedFriendsResource.class, false);
    attachProtected(router, "/users/addFriend?friendId={friendId}", AddFriendResource.class, true);
    attachProtected(router, "/users/removeFriend?friendId={friendId}", RemoveFriendResource.class, true);
    attachProtected(router, "/users/acceptFriendRequest?friendId={friendId}", AcceptFriendRequestResource.class, true);
    attachProtected(router, "/users/rejectFriendRequest?friendId={friendId}", RejectFriendRequestResource.class, true);
    
    // Scenes
    
    attachProtected(router, "/scenes/findNearbyScenes?lat={lat}&lng={lng}", FindNearbyScenesResource.class, true);
    
    // tasks
    
    attachProtected(router, "/tasks/findTasks?sceneId={sceneId}", FindTasksResource.class, true);
    attachProtected(router, "/tasks/performGeneralTask?generalTaskLevelId={generalTaskLevelId}", PerformGeneralTaskResource.class, true);

    // items
    
    attachProtected(router, "/items/listStashedItems", ListStashedItemsResource.class, true);
    attachProtected(router, "/items/listStashedItems?sceneId={sceneId}", ListStashedItemsResource.class, true);
    attachProtected(router, "/items/stashItems?inventoryItemId={inventoryItemId}&sceneId={sceneId}&count={count}", StashItemsResource.class, true);
    
    // system
    
    attachOpen(router, "/system/ping", PingResource.class, false);

    
    return router;
  }
  
  private void attachOpen(Router router, String urlTemplate, Class<? extends ServerResource> resource, boolean matchingQuery) {
    router.attach(urlTemplate, resource).setMatchingQuery(matchingQuery);
  }

  private void attachProtected(Router router, String urlTemplate, Class<? extends ServerResource> resource, boolean matchingQuery) {
    Authorizer auth = new fi.foyt.cs.oauth.protectedresource.Authorizer(Settings.getServerUrl("/oauth/authorize"));
    auth.setNext(resource);
    router.attach(urlTemplate, auth).setMatchingQuery(matchingQuery);
  }
}